/*
  SOLID - Interference Detection Library
  Copyright (C) 1997 Gino van den Bergen

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free
  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

  Please send remarks, questions and bug reports to gino@win.tue.nl,
  or write to:
                  Gino van den Bergen
		  Department of Mathematics and Computing Science
		  Eindhoven University of Technology
		  P.O. Box 513, 5600 MB Eindhoven, The Netherlands
*/

#include "Object.h"
#include "Shape.h"
#include "PointBuf.h"
#include "Detector.h"

#include <new.h>

Object::Object(DtObjectRef obj, const Shape *shape) : 
  ref(obj), 
  shapePtr(shape),
  fixedSize(false)
{
  setIdentity();
  new (&lower[X]) Endpoint(X, MIN, this);    
  new (&lower[Y]) Endpoint(Y, MIN, this);    
  new (&lower[Z]) Endpoint(Z, MIN, this);    
  new (&upper[X]) Endpoint(X, MAX, this);
  new (&upper[Y]) Endpoint(Y, MAX, this);
  new (&upper[Z]) Endpoint(Z, MAX, this);
}

void Object::setFixedSize() {
  Scalar r = shapePtr->volume().getExtent().length();
  bbox.setExtent(Vector(r, r, r));
  fixedSize = true;
}

void Object::move() {
  if (fixedSize) bbox.setCenter((*this)(shapePtr->volume().getCenter()));
  else bbox.setValue(shapePtr->volume(), *this);
  lower[X].move(bbox.lower(X));
  lower[Y].move(bbox.lower(Y));
  lower[Z].move(bbox.lower(Z));
  upper[X].move(bbox.upper(X));
  upper[Y].move(bbox.upper(Y));
  upper[Z].move(bbox.upper(Z));
}

bool intersect(const Object& a, const Object& b) {
  Transform t;
  t.setInvMult(a, b);
  return intersect(*a.shapePtr, *b.shapePtr, t);
}

int intersect(const Object& a, const Object& b, PointBuf& report) {
  report.clear();
  Transform t;
  t.setInvMult(a, b);
  intersect(*a.shapePtr, *b.shapePtr, t, report);
  for (int i = 0; i < report.size(); ++i) report[i] = a(report[i]);
  return report.size();
}

